/**
 @file ctc_asw_stp.c

 @date 2020-06-15

 @version v1.0


*/

/****************************************************************************
*
* Header Files
*
****************************************************************************/
#include "ctc_asw_common.h"
#include "ctc_asw_stp.h"
#include "asw/include/drv_api.h"

#define CTC_STP_ID_VALID_CHECK(stp_id)          \
{                                               \
    if ((stp_id) >= 32) \
    {\
        return CTC_E_BADID;\
    }\
}
/****************************************************************************
*
* Function
*
*****************************************************************************/
#define ______API______
int32
ctc_asw_stp_set_vlan_stpid(uint8 lchip, uint16 vlan_id,  uint8 stpid)
{
    IvtTable_m ivt_table;
    EvtTable_m evt_table;
    uint32      cmd = 0;
    int32       ret = 0;

    CTC_STP_ID_VALID_CHECK(stpid);
    CTC_VLAN_RANGE_CHECK(vlan_id);

    sal_memset(&ivt_table, 0, sizeof(IvtTable_m));
    sal_memset(&evt_table, 0, sizeof(EvtTable_m));

    CTC_API_LOCK(lchip);
    cmd = DRV_IOR(IvtTable_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip,vlan_id,cmd,&ivt_table));

    cmd = DRV_IOR(EvtTable_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip,vlan_id,cmd,&evt_table));
    SetIvtTable(V,ingressMstpGroupIndex_f,&ivt_table,stpid);
    SetEvtTable(V,egressMstpIndex_f,&evt_table,stpid);
    cmd = DRV_IOW(IvtTable_t,DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip,vlan_id,cmd,&ivt_table);
    cmd = DRV_IOW(EvtTable_t,DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,vlan_id,cmd,&evt_table);
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_stp_get_vlan_stpid(uint8 lchip, uint16 vlan_id,  uint8* stpid)
{
    IvtTable_m ivt_table;
    uint32      cmd  = 0;
    int32       ret = 0;
    CTC_PTR_VALID_CHECK(stpid);
    CTC_VLAN_RANGE_CHECK(vlan_id);

    sal_memset(&ivt_table, 0, sizeof(IvtTable_m));

    CTC_API_LOCK(lchip);
    cmd = DRV_IOR(IvtTable_t,DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip,vlan_id,cmd,&ivt_table);
    *stpid = GetIvtTable(V,ingressMstpGroupIndex_f,&ivt_table);
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_stp_set_state(uint8 lchip, uint32 gport,  uint8 stpid, uint8 state)
{
    IngressMstpTable_m ingress_mstp_table;
    EgressMstpTable_m  egress_mstp_table;
    uint32    cmd  = 0;
    uint32    field_val = 0;
    uint32    field_id  = 0;
    int32     ret = 0;

    CTC_STP_ID_VALID_CHECK(stpid);
    CTC_MAX_GPORT_CHECK(gport);
    CTC_MAX_VALUE_CHECK(state, 2);

    sal_memset(&ingress_mstp_table, 0, sizeof(IngressMstpTable_m));
    sal_memset(&egress_mstp_table, 0, sizeof(EgressMstpTable_m));

    CTC_API_LOCK(lchip);
    /**< [TMA] ingress mstp */
    cmd = DRV_IOR(IngressMstpTable_t,DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip,stpid,cmd,&ingress_mstp_table);
    if (state == 0)
    {
        field_val = 5;
    }
    else if (state == 1)
    {
        field_val = 2;
    }
    else
    {
        field_val = 4;
    }
    field_id = IngressMstpTable_stpStPort0_f - gport;
    DRV_SET_FIELD_V(lchip,IngressMstpTable_t,field_id,&ingress_mstp_table,field_val);
    cmd = DRV_IOW(IngressMstpTable_t,DRV_ENTRY_FLAG);
    ret = ret ? ret :  DRV_IOCTL(lchip,stpid,cmd,&ingress_mstp_table);

    /**< [TMA] egress mstp */
    cmd = DRV_IOR(EgressMstpTable_t,DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,stpid,cmd,&egress_mstp_table);
    field_val = (state == 0) ? 0 : 1;
    field_id = EgressMstpTable_stpStPort0_f - gport;
    DRV_SET_FIELD_V(lchip,EgressMstpTable_t,field_id,&egress_mstp_table,field_val);
    cmd = DRV_IOW(EgressMstpTable_t,DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,stpid,cmd,&egress_mstp_table);
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_stp_get_state(uint8 lchip, uint32 gport, uint8 stpid, uint8* state)
{
    IngressMstpTable_m ingress_mstp_table;
    uint32    cmd  = 0;
    uint32    field_val = 0;
    uint32    field_id  = 0;
    int32     ret = 0;

    CTC_PTR_VALID_CHECK(state);
    CTC_STP_ID_VALID_CHECK(stpid);
    CTC_MAX_GPORT_CHECK(gport);

    sal_memset(&ingress_mstp_table, 0, sizeof(IngressMstpTable_m));

    CTC_API_LOCK(lchip);
    /**< [TMA] ingress mstp */
    cmd = DRV_IOR(IngressMstpTable_t,DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip,stpid,cmd,&ingress_mstp_table);
    field_id = IngressMstpTable_stpStPort0_f - gport;
    field_val = DRV_GET_FIELD_V(lchip,IngressMstpTable_t,field_id,&ingress_mstp_table);
    if (field_val == 5 || field_val == 0)
    {
        *state = 0;
    }
    else if (field_val == 2)
    {
        *state = 1;
    }
    else
    {
        *state = 2;
    }
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_stp_clear_all_inst_state(uint8 lchip, uint32 gport)
{
    IngressMstpTable_m ingress_mstp_table;
    EgressMstpTable_m  egress_mstp_table;
    uint8  stp_id = 0;
    uint32 cmd = 0;
    int32  ret = 0;
    uint32 field_id  = 0;
    uint32 field_val = 0;

    CTC_MAX_GPORT_CHECK(gport);

    sal_memset(&ingress_mstp_table, 0, sizeof(ingress_mstp_table));
    sal_memset(&egress_mstp_table, 0, sizeof(egress_mstp_table));

    CTC_API_LOCK(lchip);
    for (stp_id  = 0; stp_id < 32; stp_id++)
    {
        field_id = IngressMstpTable_stpStPort0_f - gport;
        DRV_SET_FIELD_V(lchip,IngressMstpTable_t,field_id,&ingress_mstp_table,field_val);
        cmd = DRV_IOW(IngressMstpTable_t,DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip,stp_id,cmd,&ingress_mstp_table);

        field_id = EgressMstpTable_stpStPort0_f - gport;
        DRV_SET_FIELD_V(lchip,EgressMstpTable_t,field_id,&egress_mstp_table,field_val);
        cmd = DRV_IOW(EgressMstpTable_t,DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,stp_id,cmd,&egress_mstp_table);
    }
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_stp_init(uint8 lchip, void* stp_global_cfg)
{
    return CTC_E_NONE;
}

int32
ctc_asw_stp_deinit(uint8 lchip)
{
    return CTC_E_NONE;
}
